home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c-part1 / 2210 < prev    next >
Encoding:
Text File  |  1996-08-05  |  12.3 KB  |  315 lines

  1. Path: newshost.lanl.gov!tanmoy
  2. From: tanmoy@qcd.lanl.gov (Tanmoy Bhattacharya)
  3. Newsgroups: comp.lang.c
  4. Subject: Re: Problem with c code, please help!
  5. Date: 19 Jan 1996 16:27:32 GMT
  6. Organization: Los Alamos National Laboratory
  7. Message-ID: <TANMOY.96Jan19092732@qcd.lanl.gov>
  8. References: <surgsw-1901960148530001@128.206.206.86>
  9.     <mikedorman-1901960725380001@205.148.200.150>
  10. NNTP-Posting-Host: qcd.lanl.gov
  11. Mime-Version: 1.0
  12. Content-Type: text
  13. In-reply-to: mikedorman@cedarnet.com's message of Fri, 19 Jan 1996 07:25:37 -0600
  14.  
  15. --text follows this line--
  16. I try to avoid posting in a hurry ... but this post needs to be responded to. 
  17.  
  18. In article <mikedorman-1901960725380001@205.148.200.150>
  19. mikedorman@cedarnet.com (Mike Dorman) writes: 
  20. <snip>
  21.    > I have been trying to get this very simple piece of code to work for
  22.    > hours.  What is the problem???????
  23.    > 
  24.    > #include <stdio.h>
  25.    > 
  26.    > main()
  27.    > {
  28.    >    int i=0;
  29.    >    char  word[100], c;
  30.  
  31.    word is an array of 100 chars, there are no pointers declared here.
  32.    change word to this:
  33.      char *word;
  34.    and it will be *much* easier.
  35.  
  36. Please do _not_ do that! Never use a pointer where an array will do. 
  37.   1) Arrays will typically be optimized far better by the compiler
  38.      because it does not have to check for aliasing. In this
  39.      particular context, a good compiler _could_ have assumed
  40.      `noalias' anyway: but not all compilers are that good.
  41.   2) Pointers are more `powerful' than arrays: and hence can cause
  42.      more subtle errors than arrays.
  43.   3) Pointers need to point to allocated memory: a point which the
  44.      poster seems to have completely missed. A pointer cannot be used
  45.      without making it point somewhere.
  46.  
  47.    >    printf("Enter a word:   ");
  48.    >    while( (c = getchar()) != '\n')  {
  49.  
  50. This statement is dangerous: you are not testing to see if input is
  51. exhausted before the line has ended. Such things can happen.
  52.  
  53.    >       *word = c;
  54.    here, replace *word (which is a pointer to something...you didn't specify
  55.    which char in word you wanted it to point to, so it could be pointing to
  56.    just about anything) with
  57.  
  58. void flame() {
  59.  
  60. Please do not respond if you do not know C. Some may say that you
  61. learn by making mistakes ... if you want to do that please make
  62. absolutely clear that you have no knowledge of C and are trying to
  63. learn by throwing around random ideas. _My_ time is wasted responding
  64. to this post, in case the original poster perchance believes you
  65. (Sorry, original poster; beginners will often believe _anything_). I
  66. do not appreciate that; and hence would suggest that you learn the
  67. basics by the more conventional means.
  68.  
  69. }
  70.  
  71. *word is _not_ a pointer. * means take the object that it points
  72. to. word is an array, which when used in expressions (other than as an
  73. operand of & or sizeof) decays to a pointer to the _first_ element of
  74. the array. Note that there is no ambiguity about which character of
  75. the word is meant. *word itself is that character, not a pointer.
  76.  
  77.        strcat(word, *c);
  78.  
  79. And if word were pointng nowhere, did you think that strcat would
  80. magically make it point somewhere?
  81.  
  82. Actually what the original poster wanted could be most succinctly
  83. written as word[i++] = c. (Assuming a int i=0 at the top) This is a
  84. statement that sets the ith element (counting 0th element, 1st element
  85. etc.) of word to c, and increments i in preparation for the next
  86. store. Of course, the loop should check that i < sizeof word. (or, rather,
  87. sizeof word - 1 to save space for the closing null character).
  88.  
  89.    which will copy c onto the end of word, adding the character to word.
  90.    >       word == word + 1;
  91.    you don't need this...just get rid of it.
  92.  
  93. == is the comparison operator, not the assignment operator. In this
  94. you are comparing whether a pointer to the first character of word is
  95. the same as the one to the second, and doing nothing with the result.
  96.  
  97. Remember that word is an array, only in contexts where a _value_ is
  98. needed, a pointer to the first character is taken to be its value. One
  99. can change a pointer variable to point to some other place, one
  100. obviously cannot change a value! (A related example is that you can
  101. say i = 6, but i+0 = 6 is not valid.)
  102.  
  103. If word were a pointer pointing somewhere valid, then both word++ and
  104. word = word + 1 would have worked. Thus instead of the int i = 0
  105. method suggested above, you can use char *ptr = word, and then instead
  106. of writing word[i++] = c, you can write *ptr++ = c, and instead of
  107. checking i < sizeof word - 1, you can check ptr < &word[sizeof word -
  108. 1]. 
  109.  
  110.    >    }  
  111.    >    printf("You entered:  ");  
  112.    >    *word = 0;
  113.  
  114. A stylistic issue: interchange the above two lines. *word=0 (or the
  115. valid replacement *ptr = 0 or word[i] = 0 depending on the method
  116. chosen) has presumably nothing to do with your writing out the stuff,
  117. but more to do with reading in the stuff and making it into a valid
  118. `string'. As such, it should come closer to the block reading in the
  119. stuff, than writing it out. (Of course, if you consider adding the 0
  120. to be a hack designed at writing the stuff out easily, it is different
  121. matter.)
  122.  
  123.    >    while( *word != '\n' )   
  124.  
  125. Now I do not follow your logic. If you thought that word has been
  126. changing all the while, then word is already at the end of everything,
  127. how did you think of getting to the characters stored in the array
  128. (which are before word) by incrementing word?
  129.  
  130. There is a slight possiblity that you thought *word=0 puts word back
  131. to the beginning of the characters that you stored. (That would
  132. explain the placement of the statement.) Unfortunately, it does
  133. nothing of that sort: there is nothing which keeps track of where your
  134. pointer pointed at the beginning. *word=0 just sets the character that
  135. word is pointing at to be zero. This is the conventional way of
  136. representing the spot where a character string ends ... so that 
  137. a pointer can step through the word and always figure out whether it
  138. has reached the end. (Of course, this method does not work if you are
  139. trying to store real 0's in the word: but that is rare.)
  140.  
  141. Second, if you look carefully at the readin loop above, I think that
  142. you did not actually store the '\n'. So how do you expect to find it
  143. now? 
  144.  
  145. What you probably wanted was
  146.  
  147. for (i = 0; word[i] != 0; i++) {
  148.  
  149. or
  150.  
  151. for (ptr = word; *ptr != 0; ptr++) {
  152.  
  153. Note that in both cases, either i or ptr is set back to its initial
  154. value by the programmer: the programmer has to remember what the
  155. initial value was. This is the reason why even if word++ were allowed
  156. to change word, it would not have been the best thing to use here.
  157.  
  158.    >    {  
  159.    >       putchar( *word );
  160.    >       word == word + 1; 
  161.    >    }
  162.  
  163. I hope you can correct this loop now. Note also that whether you
  164. stored the '\n' or not, it is always a good idea to write out a
  165. '\n'. I do not like to use programs which needlessly leave incomplete
  166. output lines.
  167.  
  168.    Just get rid of that whole while loop, and replace it with:
  169.     puts(word);
  170.  
  171.    > }  
  172.    > 
  173.    > I think the problem I am having is due to my not knowing when to use the
  174.    > '*' operator.  When do you use it?  Also, why won't my goddam compiler let
  175.  
  176.    Ok, one problem at a time...
  177.  
  178.    When you say "char word[100]", that defines a object (and object it
  179.    anything in memory) called word, that contains 100 chars (or 100 byte
  180.    values).  So, later when word is referenced (like any array) you need to
  181.    tell the compiler which value in the array you want by adding brackets to
  182.    the end (so, if you wanted the first char in word, you'd say word[0])
  183.    (arrays are referenced from *ZERO* so array[0] is really the first value
  184.    in the array).
  185.  
  186. correct. It is usually called the first element, because the word
  187. `value' is reserved to contrast against an `lvalue' or an
  188. `object'. array[0] is an lvalue (which means it is an object) which
  189. can usually be assigned to, taken the address of, etc. (unless
  190. prohibited by some other rule.)
  191.  
  192.    When you use the * operator, that returns a pointer to something.  So
  193.  
  194. operators never `return' anything. only functions `return'
  195. something. operators operate on operands and produce lvalues or
  196. (r)values as the situation demands.
  197.  
  198. * operates on a pointer.
  199.  
  200.    *word returns a pointer to word, an array of chars.  I'm not sure how
  201.  
  202. *word is an lvalue which is exactly the same object that word points
  203. to. 
  204.  
  205.    standard C deals with this, but i would recommend not doing it that way. 
  206.    If you needed a pointer to a string from a char array (which is kindof
  207.    what you need, sortof) you'd get one by getting a pointer to the first
  208.    char (*word[0]).
  209.  
  210. Here I am totally lost (or rather, given that you did not actually ask
  211. any question: you assumed you knew; I do not want to take the time off
  212. to figure out all your misconceptions.
  213.  
  214.    Also, when getting string information from the user, you probably
  215.    shouldn't use a char array (I know it seems to make more sense that way,
  216.    but soon it'll become clear that it doesn't), but you should use a string
  217.    pointer, like this:
  218.       char *word;
  219.    Now, word is a pointer to a string, which has no specific or limited
  220.    length.  Then you can use the standard functions like strcpy and strcat to
  221.    work on string pointers.
  222.  
  223. Bogus and dangerous advice from someone who will suffer trying to
  224. write correct C programs, unless remedial measures are taken immediately.
  225.  
  226.    To do it with an array, you need another variable to keep track of how
  227.    many characters you've already put into word, so you can index the array
  228.    correctly:
  229.  
  230.  
  231.  
  232.    main()
  233.    {
  234.       char word[100], c;
  235.       int i;
  236.       i = 0;
  237.  
  238.       puts("Enter a word:");
  239.       while((c = getch()) != \n)
  240.       {
  241.      word[i] = c;
  242.      i++;
  243.       }
  244.  
  245.       puts("You entered: ");
  246.       puts(*word[0]);
  247.  
  248. Did you try to compile this? Did your compiler make sense of this
  249. line? This is comp.lang.c, not comp.lang.garbage.
  250.  
  251. In any case, how did you expect puts to know where the string ends?
  252.  
  253.    }
  254.  
  255.    But, if you did it with a string pointer, it's this much easier:
  256.  
  257.    main()
  258.    { 
  259.       char *word;
  260.  
  261.       puts("Enter a word: ");
  262.       while(scanf("%s", word) != 0)
  263.  
  264.       puts("You entered: ");
  265.       puts(word);
  266.    }
  267.  
  268. God! If thou exist, save this newsgroup from such absolute
  269. idiocies. Where do you think scanf writes the word in to? Where does
  270. word point? Didn't you even stop to think once that a pointer needs to
  271. `point' somewhere?
  272.  
  273.    > me do word++; instead of word == word +1;   I also tried to do *word++;
  274.    > and it didn't work, what is the deal with that.  It won't let me put word
  275.    > = word + 1;.  It insists on the double ='s.  Why is that?
  276.  
  277.    Are you *SURE*??  There is a difference between = and == in C.  = is
  278.    actually the assignment operator (ie: in a = b, a is assigned the value of
  279.    b).  == is the equality test operator (ie: 1 == 1 returns TRUE (1) ).  So,
  280.    word == word + 1 would alwas return false.  You should be able to do
  281.    word++ (although probably the reason why you couldn't here was because
  282.    word was an array of chars and the compiler didn't know what to do with
  283.    word, it would've been ok if you did word[0]++, but you wouldn't have
  284.    needed it anyway. 
  285.  
  286.    > ps: is there a way to find out what exactly error messages mean?  I kept
  287.    > getting something similar to: not an Ivalue.  It would be nice if I knew
  288.    > what the hell that meant.
  289.  
  290.    An lvalue is a value that can be assigned to.  For instance, if you had 3
  291.    = b + 2, the compiler would complain about the 3 because you can't store
  292.    another value to 3.  It probably complained about word = word + 1 because
  293.    word is a "constant" that defines the beggining of the char array.  I
  294.    don't really know what you get from "word" if you have a "char word[100]"
  295.    array, except something really wierd, so you probably shouldn't use it.
  296.  
  297. You would have known what `you get from word' and have used it
  298. happily, if you just bothered to look at the FAQ before posting. Most
  299. FAQs are available from rtfm.mit.edu
  300.  
  301.    Well, there it is!  Hope that helps!  Feel free to email me if you have
  302.    other problems.
  303.  
  304. Such absolutely incorrect advice hardly ever helps.
  305.  
  306. Cheers
  307. Tanmoy
  308. --
  309. tanmoy@qcd.lanl.gov(128.165.23.46) DECNET: BETA::"tanmoy@lanl.gov"(1.218=1242)
  310. Tanmoy Bhattacharya O:T-8(MS B285)LANL,NM87545 H:#9,3000,Trinity Drive,NM87544
  311. Others see <gopher://yaleinfo.yale.edu:7700/00/Internet-People/internet-mail>,
  312. <http://alpha.acast.nova.edu/cgi-bin/inmgq.pl>or<ftp://csd4.csd.uwm.edu/pub/
  313. internetwork-mail-guide>. -- <http://nqcd.lanl.gov/people/tanmoy/tanmoy.html>
  314. fax: 1 (505) 665 3003   voice: 1 (505) 665 4733    [ Home: 1 (505) 662 5596 ]
  315.